package org.example.config;

import org.example.filter.MyGatewayFilterFactory;
import org.example.predicate.KeywordRoutePredicateFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.util.pattern.PathPatternParser;

import java.time.ZonedDateTime;
import java.util.List;
import java.util.function.Function;

@Configuration
public class GatewayConfig {
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder,
                                           KeywordRoutePredicateFactory keywordRoutePredicateFactory
                                            , MyGatewayFilterFactory myGatewayFilterFactory
                                           , MyGatewayFilterFactory.Config customFilterConfig
                                           )
    {
        return builder.routes()
                .route("special_route",
                        r -> r.predicate(keywordRoutePredicateFactory.apply(new KeywordRoutePredicateFactory.Config("special")))
                                .filters(
                                        f -> f.rewritePath("/.*", "/"))
                                .uri("http://www.baidu.com")
                )
                .route("provider-tem-quick",
                         r->r.path("/tem/quick/")
                        .and().method("GET","POST")
                        .uri("lb://provider-tem")
                ).route("provider-tem-before",
                        r-> r.path("/tem/before")
                        .and().before(ZonedDateTime.parse("2024-04-23T00:00:00+08:00"))
                        .uri("lb://provider-tem")
                ).route("provider-tem-after",
                        r-> r.path("/tem/after")
                                .and().after(ZonedDateTime.parse("2024-04-23T00:00:00+08:00"))
                                .uri("lb://provider-tem")
                ).route("provider-tem-between",
                        r-> r.path("/tem/between")
                                .and().between(ZonedDateTime.parse("2024-04-23T00:00:00+08:00"),ZonedDateTime.parse("2024-04-24T00:00:00+08:00"))
                                .uri("lb://provider-tem")
                ).route("provider-tem-cookie",
                        r-> r.path("/tem/cookie")
                                .and().cookie("color","red")
                                .uri("lb://provider-tem")
                ).route("provider-tem-header",
                        r-> r.path("/aaa/tem/header")
                                .and().header("X-Request-Color","red")
                                .filters(
                                      f->f.stripPrefix(1)
                                      .filter(myGatewayFilterFactory.apply(customFilterConfig))
                                )
                                .uri("lb://provider-tem")
                ).route("provider-tem-host",
                        predicateSpec -> predicateSpec.path("/tem/host")
                                .and().host("*.example.org")
                                .uri("lb://provider-tem")
                ).route("provider-tem-method",
                        r-> r.path("/tem/method")
                                .and().method("GET")
                                .uri("lb://provider-tem")
                ).route("provider-tem-query",
                        r-> r.path("/tem/query")
                            .and().query("color","red")
                                .filters(
                                    f->f.addRequestHeader("name","AtM")
                                            .setRequestHeader("color","bule")
                                    .filter((exchange,chain)->{
                                        ServerHttpRequest build = exchange.getRequest().mutate().header("name1", "AtM2").build();
                                        ServerWebExchange serverWebExchange = exchange.mutate().request(build).build();
                                        return chain.filter(serverWebExchange);
                                    })
                                )
                                .uri("lb://provider-tem")
                )
                .route("test",r->r.path("/test/**")
                        .filters(
                                f -> f.setPath("/tem/test")
                        )
                        .uri("lb://provider-tem")
                )
                .build();
    }
    @Bean
    public CorsWebFilter corsWebFilter(){
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin("*"); //允许所有域名跨域
        config.setAllowCredentials(true); //允许携带cookie
        config.addAllowedMethod("GET"); //允许所有方法
        config.addAllowedMethod("POST"); //允许所有方法
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**",config); //对所有请求生效
        return new CorsWebFilter(source);

    }
    @Bean
    public MyGatewayFilterFactory.Config customFilterConfig() {
        MyGatewayFilterFactory.Config config = new MyGatewayFilterFactory.Config();
        config.setValues(List.of("value1", "value2"));

        return config;
    }
}
